//抽象tio的对外接口
#pragma once
#include <memory>
#include <vector>
#include <map>
#include "rtdev/rtdev.h"
#include <boost/circular_buffer.hpp>

namespace rtdev {

typedef enum
{
    RS485_RTU = 0,
    RS485_TRANS = 1,
    RS485_SENSOR = 2,  //tio侧，无此状态，应根据0x10a来判断
} RS485Mode;

struct RS485RTUConfig
{
    int slaveId;   ///< slave id
    int baudrate;  ///< baudrate of the modbus
    int databits;  ///< data length  7/8
    int stopbits;  ///< stop bits  1/2
    int parity;    ///< checking bits 78-> N 79->O 69->E
};

//---------------------------------//
typedef enum
{
    TIO_LAMP_AUTO = 0,
    TIO_LAMP_BLUE = 1,
    TIO_LAMP_GREEN = 2,
    TIO_LAMP_YELLOW = 3,
    TIO_LAMP_RED = 4,
    TIO_LAMP_YELLOW_TWINKLE = 5,
} TioLampColor;

struct TioKeys
{
    bool UIKey_free;
    bool UIKey_point;
    bool UIKey_pause_resume;
    bool UIKey_custome;  // ATOM 自定义按钮
};

struct TioPdoStatus
{
    int last_alive_cnt;
    int alive_watchdog;
    bool alive_flag;
};

class TioUsrIoItf
{
    // todo:
    //[] io配置和485配置互斥
    //[] 485单独抽象为一类
public:
    virtual ~TioUsrIoItf() = default;

    virtual size_t get_di_cnt() = 0;
    virtual size_t get_do_cnt() = 0;
    virtual size_t get_ai_cnt() = 0;
    virtual size_t get_ao_cnt() = 0;
    virtual int set_di(std::vector<int8_t> input) = 0;
    virtual int get_di(std::vector<int8_t>& output) = 0;
    virtual int set_do(std::vector<int8_t> input) = 0;
    virtual int get_do(std::vector<int8_t>& output) = 0;
    virtual int set_ai(std::vector<double> input) = 0;
    virtual int get_ai(std::vector<double>& output) = 0;

    virtual int set_ao(std::vector<double> input) = 0;    //当前没有该类型
    virtual int get_ao(std::vector<double>& output) = 0;  //当前没有该类型

    virtual bool is_tio_v3() { return false; }

    virtual int tio_setup_di_pin_mode(uint32_t cfg) { return -1; };
    virtual int tio_setup_do_pin_mode(uint32_t cfg) { return -1; };
    virtual int tio_setup_ai_pin_mode(uint32_t cfg) { return -1; };
    virtual int tio_setup_ao_pin_mode(uint32_t cfg) { return -1; };
    virtual int tio_get_di_pin_mode() { return -1; };
    virtual int tio_get_do_pin_mode() { return -1; };
    virtual int tio_get_ai_pin_mode() { return -1; };
    virtual int tio_get_ao_pin_mode() { return -1; };

    virtual int set_tio_rs485_chn_mode(int chn, RS485Mode mode) { return -1; };  //根据chn配置0x104 0x105参数
    virtual int get_tio_rs485_chn_mode(int chn) { return -1; };
    virtual int set_tio_rs485_chn_comm(int chn, RS485RTUConfig rtuComm) { return -1; };  //根据chn配置0x106 0x107参数
    virtual int get_tio_rs485_chn_comm(int chn, RS485RTUConfig& rtuComm) { return -1; };
    virtual int tio_set_rs485_chn_func(uint32_t cfg) { return -1; };  //0x10a 力矩传感器通道选择  考虑改名
    std::vector<boost::circular_buffer<char>> rs485_trans_buffer_;    //数据转发/透传模式下使用的数据队列
};

class TioSysIoItf
{
public:
    virtual ~TioSysIoItf() = default;
    virtual int query_Tio_version() = 0;
    virtual uint32_t get_tio_version() = 0;
    virtual int set_tio_RGB(TioLampColor color) = 0;              //set to config
    virtual int get_tio_RGB() = 0;                                //read from mem
    virtual TioKeys get_tio_keys() = 0;                           //read from mem
    virtual int tio_set_vout_enable(uint32_t cfg) { return -1; }  //only tiov3 move to tioV3
    virtual int tio_get_vout_enable() { return -1; };
    //0 for 24V, 1 for 12V
    virtual int tio_set_vout_voltage(uint32_t data) { return -1; };  //only tiov3 move to tioV3
    virtual int tio_get_vout_voltage() { return -1; };
};

class TioBoardItf : public rtdev::RtDevItf
{
public:
    static const uint16_t Tio_CONNECT_WATCHDOG = 500;
    static TioBoardItf* create(uint8_t tiotype);
    TioBoardItf();
    virtual ~TioBoardItf() = default;
    virtual int init(const char* cfgfile) = 0;
    virtual int shutdown() { return 0; }
    virtual void check_alive();
    virtual int keep_alive(int alive);
    virtual bool is_alive();
    virtual void check_alive_optional();
    virtual int keep_alive_optional(int pdo_id, int alive);
    virtual bool is_alive_optional(int pdo_id);
    virtual bool is_sim();
    virtual const char* name() = 0;
    virtual TioUsrIoItf* usrio() = 0;
    virtual TioSysIoItf* sysio() = 0;

protected:
    virtual int set_send_data(int busid = -1) = 0;
    virtual int get_recv_data(int busid = -1) = 0;

protected:
    uint8_t sim_flag_;
    int alive_watchdog_;
    bool alive_flag_;
    int last_alive_cnt_;
    std::map<int, TioPdoStatus> OptionalPdoMap_;
};

const uint8_t ktioV1 = 1;
const uint8_t ktioV2 = 2;
const uint8_t ktioV3 = 3;
class TioBoardFactoryItf
{
public:
    virtual ~TioBoardFactoryItf() = default;
    virtual TioBoardItf* create() = 0;
};

}  // namespace rtdev